package flows

import (
	"encoding/json"
	"strconv"
	"time"
	"zimuzu_cvn_web_api/model"
	"zimuzu_cvn_web_api/pkg/drive/redis"
	"zimuzu_cvn_web_api/pkg/e"
	"zimuzu_cvn_web_api/pkg/errno"
	"zimuzu_cvn_web_api/service"
)

// 获取指定线路指定日期的收益信息
func GetTheDateSourceCdnData(Date string, Source int) (res model.ProfitTotalParams, err error) {
	cacheKey := "temp:the:date:source:cdn:" + Date + "_" + strconv.Itoa(Source)
	if redis.Exists(cacheKey) {
		rS, err := redis.Get(cacheKey)
		if err != nil {
			redis.UnDelete(cacheKey)
			return res, err
		}
		err = json.Unmarshal([]byte(rS), &res)
		if err != nil {
			redis.UnDelete(cacheKey)
			return res, err
		}
		return res, nil
	}
	res, err = model.GetProfitTotalDateBySource(Date, Source)
	if err != nil {
		return res, err
	}
	rB, err := json.Marshal(res)
	if err != nil {
		return res, err
	}
	redis.SetUnRe(cacheKey, string(rB), e.TimeFormatDay)
	return res, nil
}

// 根据昨日流量获取到昨日的CDN收益
// 参数： date: 2020-03-12
// Auth: hzp
// Date: 2020-03-12
func GetTheDateCdnProfit(Date string) (profit float64, err error) {

	// source 配置
	sourceConfig, err := model.GetProfitSourceConfig()
	if err != nil {
		return profit, err
	}
	//当前cvnt对应人民币价格
	start := e.StrToTime(Date + " 00:00:00")
	end := e.StrToTime(Date + " 23:59:59")
	price, _, err := service.GetCvntPrice()
	if err != nil {
		return profit, err
	}
	var profitTotalTemp model.ProfitTotalParams
	for _, k := range sourceConfig {
		if k.Switch == 0 {
			continue
		}
		flowsAndGbps, err := _getTheDataFlowsAndGbps(start, end, k.Source)
		if err != nil {
			continue
		}
		profitTotalTemp.Date = Date
		profitTotalTemp.Source = k.Source
		profitTotalTemp.Gbps = flowsAndGbps.Gbps
		profitTotalTemp.Cvn = flowsAndGbps.Gbps * k.SettlePrice / flowsAndGbps.Days / price
		profitTotalTemp.Flows = flowsAndGbps.Flows
		profit += profitTotalTemp.Cvn
		// 逐条插入
		_ = model.AddProfitTotalData(profitTotalTemp)
	}

	return profit, nil
}

// 获取指定日期的总流量和总带宽
type TheDataFlowsAndGbpsParams struct {
	Flows int64   `json:"flows"`
	Gbps  float64 `json:"gbps"`
	Days  float64 `json:"days"`
}

func _getTheDataFlowsAndGbps(Start, End int64, Source int) (res TheDataFlowsAndGbpsParams, err error) {
	cacheKey := "temp:the:date:flows:gbps:" + strconv.FormatInt(Start, 10) + "_" + strconv.FormatInt(End, 10) + "_" + strconv.Itoa(Source)
	if redis.Exists(cacheKey) {
		rS, err := redis.Get(cacheKey)
		if err != nil {
			return res, err
		}
		err = json.Unmarshal([]byte(rS), &res)
		if err != nil {
			return res, err
		}
		return res, nil
	}
	res.Flows, err = model.GetTheDateTotalFlows(Start, End, Source)
	if err != nil {
		return res, err
	}
	res.Gbps, err = model.GetTheDateGbps(Start, End, Source)
	if err != nil {
		return res, err
	}
	rB, err := json.Marshal(res)
	if err != nil {
		return res, err
	}
	// TODO set days = 30
	res.Days = 30
	redis.SetUnRe(cacheKey, string(rB), e.TimeFormatDay)
	return res, nil
}

// 每天看板
// Auth: hzp
func DailyBoard() (err error) {

	boardDate := time.Now().AddDate(0, 0, -1).Format(e.TimeFormatD)
	err = model.CheckDailyBoardByDate(boardDate)
	if err != nil {
		return errno.ExistsRecord
	}

	var data model.DailyBoardStruct
	// 节点数据
	data.NodeNums, err = model.GetNodeNumsByType(1)
	if err != nil {
		return err
	}
	e.Log("err", "每天看板 节点数据已处理完成")
	data.OnlineNums, err = model.GetNodeNumsByType(2)
	if err != nil {
		return err
	}
	e.Log("err", "每天看板 在线节点数据已处理完成")
	data.CreateNums, err = model.GetNodeNumsByType(3)
	if err != nil {
		return err
	}
	e.Log("err", "每天看板 新增节点数据已处理完成")
	// 质押数据
	data.PledgeCvn, err = model.GetGlobalCvnFrozen(model.PledgeLinux)
	if err != nil {
		return err
	}
	e.Log("err", "每天看板 质押数据已处理完成")
	unPledgeNums, err := model.GetUnPledgeNodeNum()
	if err != nil {
		return err
	}
	data.UnPledgeCvn = unPledgeNums * e.SinglePledgeCvn

	// 带宽数据
	data.OutPut, err = GetTheDateCdnProfit(boardDate)
	if err != nil {
		return err
	}
	e.Log("err", "每天看板 带宽数据已处理完成")
	// 存储数据
	data.Storage, err = model.GetNetStorage()
	if err != nil {
		return err
	}
	e.Log("err", "每天看板 存储数据已处理完成")

	err = model.AddDailyBoardData(data)
	if err != nil {
		e.Log("err", "每天看板 处理失败：", err.Error())
		return err
	}

	return nil
}
